package com.ding.easycontroller.service.impl;

import com.ding.easycontroller.dao.PluginDao;
import com.ding.easycontroller.plugin.PluginConfig;
import com.ding.easycontroller.service.PluginService;
import easycontroller.plugin.Plugin;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.script.ScriptEngine;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/*

    插件不能删除只能停用
    插件只能导入不能不能写入
    插件可以配置后重启
    平台可以向插件暴露部分接口,但需要在配置中添加信任

    自定义类加载器加载jar包下的类文件



 */
@Service
public class PluginServiceImpl implements PluginService {


    @Autowired
    private ScriptEngine scriptEngine;

    @Autowired
    private PluginDao pluginDao;

    private List<Plugin> plugins;

    private Map<String, PluginConfig> pluginConfigMap;

    private void statement(Plugin plugin) {
        try {
            String name = plugin.getName();
            ScriptObjectMirror plugins = (ScriptObjectMirror) scriptEngine.eval("plugins;");
            plugins.put(name, plugin);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void init() {

        //读取配置文件
        pluginConfigMap = pluginDao.readConfigs();

        //获取所有插件
        plugins = pluginDao.listAll();

        //移除名称不规则的插件
        plugins.removeIf(p -> p.getName() == null || !p.getName().matches("[a-zA-Z_][a-zA-Z0-9_]*"));

        //配置插件
        for (Plugin plugin : plugins) {
            PluginConfig pluginConfig = pluginConfigMap.get(plugin.getName());
            if (pluginConfig != null) {
                plugin.setConfig(pluginConfig.getConfig());
                if (pluginConfig.isEnable()) {
                    try {
                        //尝试启用插件
                        start(plugin.getName());
                        statement(plugin);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    @Override
    public List<Plugin> getEnablePlugins() {
        List<Plugin> r = new ArrayList<>();
        for (Plugin plugin : plugins) {
            if (plugin.isEnable()) {
                r.add(plugin);
            }
        }
        return r;
    }

    @Override
    public List<Plugin> getAllPlugins() {
        return plugins;
    }

    @Override
    public Plugin getByName(String name) {
        for (Plugin plugin : plugins) {
            if (plugin.getName().equals(name)) {
                return plugin;
            }
        }
        return null;
    }

    @Override
    public void start(String name) {
        Plugin plugin = getByName(name);
        if (plugin == null) {
            throw new RuntimeException("插件不存在");
        }
        plugin.start();
        plugin.setEnable(true);

        updateOrAddConfig(plugin);

    }

    @Override
    public void restart(String name) {
        Plugin plugin = getByName(name);
        if (plugin == null) {
            throw new RuntimeException("插件不存在");
        }

        if (plugin.isEnable()) {
            plugin.restart();
        }

    }

    private void updateOrAddConfig(Plugin plugin) {

        //获取名称
        PluginConfig config = pluginConfigMap.get(plugin.getName());

        if (config == null) {
            config = new PluginConfig();
            config.setName(plugin.getName());
            config.setEnable(plugin.isEnable());
            config.setConfig(plugin.getConfig());
            pluginConfigMap.put(plugin.getName(), config);
            pluginDao.addConfig(config);
        } else {

            boolean flag = false;
            if (plugin.isEnable() != config.isEnable()) {
                config.setEnable(plugin.isEnable());
                flag = true;
            }

            if (plugin.getConfig() != config.getConfig()) {
                config.setConfig(plugin.getConfig());
                flag = true;
            }

            if (flag) {
                pluginDao.updateConfig(config);
            }

        }

    }

    @Override
    public void config(String name, Map<String, String> config) {

        Plugin plugin = getByName(name);
        if (plugin == null) {
            throw new RuntimeException("插件不存在");
        }

        plugin.setConfig(config);

        updateOrAddConfig(plugin);

        if (plugin.isEnable()) {
            plugin.restart();
        }

    }

    @Override
    public void stop(String name) {
        Plugin plugin = getByName(name);
        if (plugin == null) {
            throw new RuntimeException("插件不存在");
        }
        plugin.stop();
        plugin.setEnable(false);
        updateOrAddConfig(plugin);

    }


}
